Here are the most asked for examples. They realy do work as they have been typed into a MP2k and executed.
Example #1 - Put the date into a field so that later it can be used in calculations or sorted.
"Run Script always" is checked.
If RecordAction = 'NewMain then begin // only execute this part if a new record is made.
local nTime := time(); // get the time in minutes
local TTime := :ToString(nTime); // make time into text
local DbRecord := :GetEntry(CurrentDbCursor); // get the current record being displayed
:SetField(CurrentDb, DbRecord, 8, TTime); // set the time (as text) into field #8
:SaveEntry(DbRecord); // save the record
end;
local rTime := :GetField(CurrentDbEntry,8); // get field #8 in the current record on screen
:Show(:FormDateString(:toNumber(rTime))); // show the formatted date on the screen, first changing the date to a number
The above sets the current time into a field (#8) in the current screens database when a New record is made. It shows that date formatted (YY/MM/DD or whatever you have the Date format set to) on the screen where the NS button is. You don't put field #8 on the screen, if you do , it will show up as a number.
It also demonstrates two ways to access the current record on the screen. First by using the var: CurrentDbCursor and then by using the var: CurrentDbEntry.
-----------------
Example #2: Display the Date Calendar to pick a date.
// Do NOT delete the following line or else there might be a memory leak.
// There is a MP2K ROM problem with the postkeyString()
// function if there is no receiver of the text.
self.pickActionScript := func(sd) // this is callback, it is not directly executed
begin
:Show(:formdatestring(sd[0])); // show the date picked in the NS button
// use the below 2 lines to put the date as a number into an edit field
if DataformClick = 0 then return; // no edit field is open
postkeyString('viewFrontKey,:toString(sd[0]));
// use the 2 lines below to put the date as formatted (YY-MM-DD or whatever your prefs are set to) into the edit field.
if DataformClick = 0 then return; // no edit field is open
// use the below 3 lines to put the date (as a text number) into a database field
:SetField(CurrentDbEntry, DbRecord, 8, :toString(sd[0])); // set the time (as text) into field #8 of the on screen Db
:SaveEntry(DbRecord); // save the record
inherited:?pickActionScript (sd); // call the internal script
NsVar.a:=nil; // remove (most) storage
end;
self.pickCancelledScript := func() // this is callback, it is not directly executed
begin
inherited:?pickCancelledScript(); // call the internal script
NsVar.a:=nil; // remove (most) storage
end;
local p := @317; // internal magic pointer for a Date Popup
NsVar.a :=buildContext(p); // make it into a view and save a reference to it
// this bounds frame can be used to make the date popup show on the left side of the screen
//local w:= {top:5,left:5,bottom:6,right:6};
// or the bounds frame below will show the date popup on the left side
local w :=getroot():globalbox();
NsVar.a:new([time()],w, self); // shows the date popup, when used taps [x] box, then PickActionScript is executed
The above code will pop up a Date calendar for selection of a Date. Three options are given as what to do with the date a user selects.
----------
Example #3 - Calculate a total of a field. Set the script to always run.
local t :=0; // the var that holds tht total
if NSvar.PartTotal and not ButtonHit then // check if a total exists
begin
t := NSvar.PartTotal; // total already exists , so use it
end;
else begin
:Show("Calculating ..."); // a total doesn't exist, so calculate
local c :=:GetCursor(7, 0); // get a cursor for Db #7 using index #0
If NsError then begin
:ShowError("Opps, the database/index doesn't exist");
return;
end;
local e:= :GetEntry(c); // get the first record from the Db
while e do // loop while there are more records
begin
local nt :=:GetField(e, 2); // get data from field #2
If NsError then
:Show("Opps, the Field doesn't exist in that record");
local n := :ToNumber(nt); // convert to number
If NsError then
:Show("Opps, a field didn't contain a number");
else
t:=t+n; // add to total
e:=:NextEntry(c) // get next record from database
end;
end;
:Show("Total: " & :ToString(t)); // convert total back to text and show on the screen
NSvar.PartTotal := t; // put the number in the NS save frame
:SaveNSvar(); // save the vars for next time
You may want to add some more initial conditions to recalculate the total based on a changed field, added or deleted record.
----------
Example #4 - Print a multi column report
// this prints a multi column report
local MyTabs := [100,200]; // tabs are in pixels, held in an array. you may set up to 8 tab stops
setvalue(PrintPage.ppt, 'tabs, MyTabs); // set the tabs
local DbCursor := CurrentDbCursor; // cursor for screen db including any Query that is active
:ResetCursor(DbCursor); // set cursor to start of database
local Page := 0; // init page number
Local MainTitle := "\tSample Report"; // the report title, at 1st tab stop
local ColumnTitle := "Item\tCost\tPart Number"; // the column titles, at the tab stops
local DbEntry := :GetEntry(DbCursor); // get 1st record
local T := MainTitle & "\n" & ColumnTitle ; // report text goes into 'T', start with the heading
local Lines := 0; // count lines per page
:show("Printing page 1"); // update stats
While DbEntry do begin // loop for all records
// get the data to be used
local t0 := :GetField(DbEntry, 0); // field #0 is 1st column
local t1 := :GetField(DbEntry, 1); // field #1 is 2nd column
local t2 := :GetField(DbEntry, 2); // field #2 is 3rd column
// if more than 3 fields, then add here, like:
// local t3 := :GetField(DbEntry, 3); // field #3 is 4th column
// and add: ' & "\t" & t3 ' (no single quotes) to the line below so that data is appended to the other data
T := T & "\n" & t0 & "\t" & t1 & "\t" & t2; // put all data together, separated with tabs
Lines := lines +1; // increment line counter
if lines > 50 then begin // when we hit 50 lines, print the page to the notepad
Page := page +1; // increment page counter
:show("Printing page"&:toString(page)); // update status
Lines := 0; // reset line counter
T := T & "\n\tPage: "&:ToString(page); // add page number to page of text
:MakeNote(T); // put all the report text to a note in the notepad
T := MainTitle & "\n" & ColumnTitle ; // init report heading for next page
end;
if NsError then begin // if there was any error, give up
:show("Error: " & :ToString(NsError));
return;
end;
DbEntry := :NextEntry(DbCursor); // get next record
end;
if Lines > 0 then begin // after last record, print last page
T := T & "\n\tPage: "&:ToString(page+1);
:MakeNote(T);
end;
:Show("Print Done");
Notes:
Set the MyTabs array to as many (up to 8) tab stops as needed for up to 9 columns of data.
Change the number of lines per page (NotePad note) by changing the "if lines > 50 then begin " to another number, but remember that a Note should be less than 8k is size.
In the NotePad, you can switch to OverView and select multiple items to print/fax/email as one job.
-----------
Example #5 - Make a FileMaker type Portal showing multiple fields of multiple records
NsDontClick:=true; // set NS window so it can't be clicked
local myTabs := [100,200]; // there will be 3 coulmns so set 2 (max: 8) tab stops. Tabs are in pixels
SetValue(self, 'tabs, MyTabs); // set the tabs to the button view
DbNumber := 6; // the database to get the records from
MatchFieldNumber := 0; // the field to find a match in. Use an Indexed field for fast lookups and then the data fetched will be in order. Non-indexed searches are SLOW and out of order.
MatchDataStr := "d"; // the match data. As many or few chars as you want. This could be data from a record.
local DbEntryCursor := :GetDbIndirectRecord(DbNumber, MatchFieldNumber, MatchDataStr); // get the 1st record that matches 'MatchDataStr'
local DbEntry:= DbEntryCursor.DbEntry; // get the matched record entry
local DbCursor:= DbEntryCursor.DbCursor; // get the cursor that points to the matched record
If not DbEntry // check to see if there was indeed a match
then begin
:Show("No Records to display"); // if no matched record, then exit
return;
end;
local max := 9; // there was a matched record, so now fetch nine more
local t := "Part\tNumber\tCost"; // define the title
if DbCursor then // if there is a cursor then start the loop. May be not needed
while DbEntry do // loop while getting records
begin
// form the data to be displayed by putting a <cr> at the start of each line
// and a tab (\t) before the 2nd and 3rd data columns.
t := t & "\n"& :GetField(DbEntry, 0) & "\t" & :GetField(DbEntry, 1) & "\t" & :GetField(DbEntry, 2);
max := max - 1; // decrement max records to fetch counter
if max < 0 then break; // break out of 'while loop' if all fetched
DbEntry := :NextEntry(DbCursor); // get the next record
end; // end of loop
:Show(t); // show all fetched records on screen.
----------
Example #6 - Math
local n1 := :ToNumber(:GetField(CurrentDbEntry, 1)); // get data from field #1 of on screen Db
local n2 := :ToNumber(:GetField(CurrentDbEntry, 2)); // get data from field #2 of on screen Db
local t := n1 + n2; // add field #1 and field #2, save in 't'
:show("Total =" & :ToString(t)); // display the result
----------
Example #7 - Popup List
local aList := ["A","B","C"]; // define an array of the items to popup
addArraySlot(aList, 'pickseparator); // add a separator line in the list
addArraySlot(aList, "D"); // add some more data to the list
// pop up the list on the screen.
// The 2nd and 3rd parameters of 'dopopup' are offsets (X,Y)
// that indicate how far from the button you want the list to appear on the screen.
dopopup(aList,0,0,self);
// this is a callback routine that gets executed only when an item in the popup list is selected
self.pickActionScript :=
func(selected)
begin
// show which item was selected
// items start at 0. Even pickseparator's take space but you can't select them, thus it's
// this is a callback routine that gets executed only when no item in the list is selected
// if you don't want to do anything when no item is selected, this doesn't need to be entered.
self.pickCancelledScript :=
func()
begin
:show("nothing");
end;
Notes: You can make a popup containing dynamic data, perhaps a list of data of a field from all records in a database by using the addArraySlot function while retrieving the field data in a loop and then, when the user selects an item in the popup list, putting the selection data into a record. See other examples on how to retrieve the record data & putting data into a record.